import cython
cimport perlin

#cython: boundscheck=False
#cython: wraparound=False
#cython: cdivision=True

cdef int CHUNK_X_SIZE, CHUNK_Y_SIZE, CHUNK_Z_SIZE  

@cython.locals(xblks=dict, yblks=dict, zblks=dict, x=int, y=int, z=int)
cpdef dict init_3d_list(int x_size, int y_size, int z_size)

cdef class Chunk:
    cdef public:
        int x_pos, y_pos, z_pos
        int x_size, y_size, z_size
        dict blocks

    cdef get_block(self,int x, int y, int z)

    cdef set_block(self,int x, int y, int z, object block)

    cdef int world_block_xpos(self, int x)

    cdef int world_block_ypos(self, int y)

    cdef int world_block_zpos(self, int z)

cdef int SAMPLE_RATE_HOR, SAMPLE_RATE_VER

cdef class TerrainGeneratorBase:
    cdef public object seed

    cpdef object generate_sector(self, sector)

cdef class TerrainGenerator(TerrainGeneratorBase):
    cdef public:
        object base_gen
        object ocean_gen
        object river_gen
        object mount_gen
        object hill_gen
        object cave_gen
        object biome_gen

    cpdef object set_seed(self, object seed)

    @cython.locals(c=Chunk, d_map=dict, x=int, y=int, z=int, biome_type=int, first_block=int, den=double)
    cpdef object generate_chunk(self, object chunk_x, object chunk_y,
                                object chunk_z)

    cpdef Chunk gen_inner_layer(self, int x, int y, int z, Chunk c)

    @cython.locals(depth=int, biome_type=int)
    cpdef Chunk gen_outer_layer(self, int x, int y, int z,
                                 object first_block, Chunk c,
                                 object biome_type)

    cpdef double lerp(self, float x, float x1, float x2, float v00,
                      float v01)

    @cython.locals(u=double, v=double)
    cpdef double tri_lerp(self, float x, float y, float z, float v000,
                          float v001, float v010, float v011, float v100,
                          float v101, float v110, float v111, float x1,
                          float x2, float  y1, y2, float z1, float z2)

    @cython.locals(x=int, y=int, z=int, offsetX=int, offsetY=int, offsetZ=int)
    cpdef dict tri_lerp_d_map(self, dict d_map)

    cpdef double _clamp(self, double a)

    cpdef double density(self, int x, int y, int z)

    cpdef double base_terrain(self, int x, int y)

    cpdef double ocean_terrain(self, int x, int y)

    cpdef double rive_terrain(self, int x, int y)

    cpdef double mount_density(self, int x, int y, int z)

    cpdef double hill_density(self, int x, int y, int z)

    cpdef double cave_density(self, int x, int y, int z)


cdef class TerrainGeneratorSimple(TerrainGeneratorBase):
    cdef public:
        object world
        object rand
        object weights
        object noise
        bint skip_over
        double PERSISTENCE
        double H
        int OCTAVES
        int height_range
        int height_base
        int island_shore
        int water_level
        double zoom_level
        tuple lowlevel_ores
        tuple midlevel_ores
        tuple highlevel_ores
        tuple underwater_blocks
        tuple world_type_trees
        tuple world_type_plants
        tuple world_type_grass
        tuple island_type_grass
        tuple leaf_blocks
        set autogenerated_blocks
        int negative_biome_trigger
        object biome_generator
        tuple nether

    cpdef double _clamp(self, double a)

    @cython.locals(y=double, weight=double)
    cpdef int get_height(self, double x, double z)

    @cython.locals(world=object, islandheight=int, skip=bint, bx=int,
                   by=int, bz=int, bytop=int, x=int, z=int, y=int, yy=int)
    cpdef object generate_sector(self, object sector)
